Skip to content

Conversation

@larseggert
Copy link
Collaborator

@codecov
Copy link

codecov bot commented Jan 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.02%. Comparing base (967105c) to head (401f12e).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3337      +/-   ##
==========================================
- Coverage   94.21%   94.02%   -0.20%     
==========================================
  Files         125      130       +5     
  Lines       37712    38099     +387     
  Branches    37712    38099     +387     
==========================================
+ Hits        35530    35821     +291     
- Misses       1339     1425      +86     
- Partials      843      853      +10     
Flag Coverage Δ
freebsd 78.55% <ø> (?)
linux 94.20% <ø> (?)
macos 94.08% <ø> (?)
windows 94.19% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 98.49% <ø> (ø)
neqo-crypto 86.35% <77.00%> (-0.71%) ⬇️
neqo-http3 93.87% <88.05%> (-0.02%) ⬇️
neqo-qpack 94.79% <100.00%> (+<0.01%) ⬆️
neqo-transport 95.09% <92.02%> (-0.01%) ⬇️
neqo-udp 82.47% <ø> (-0.43%) ⬇️
mtu 86.61% <100.00%> (ø)

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 21, 2026

Merging this PR will degrade performance by 9.33%

❌ 3 regressed benchmarks
✅ 35 untouched benchmarks
⏩ 8 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime walltime/pacing-true/same-seed 91.9 ms 97.7 ms -5.9%
Memory walltime/1000-streams/each-1000-bytes 833.9 KB 868.9 KB -4.03%
Memory walltime/1000-streams/each-1-bytes 706.2 KB 778.9 KB -9.33%

Comparing larseggert:feat-mtu-no-bindgen (401f12e) with main (0392725)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Member

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I'm following the CI parts, but don't you want CI to (mostly) just check that what is generated matches what is in the tree? But then you might also have CI propose a PR to update what is in-tree on the affected branch.

@larseggert
Copy link
Collaborator Author

larseggert commented Jan 21, 2026

But then you might also have CI propose a PR to update what is in-tree on the affected branch.

That is probably overkill. I don't really expect these bindings to ever change, since OSs have ABI promises.

Edit: But Rust version changes may cause bindgen to generate slightly different bindings. Let me look into the PR thing.

@larseggert larseggert marked this pull request as ready for review January 21, 2026 09:21
Copilot AI review requested due to automatic review settings January 21, 2026 09:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the bindgen build dependency from the MTU crate by replacing runtime binding generation with pre-generated platform-specific binding files. Instead of using bindgen during the build process, the PR checks in generated binding files for each supported platform (Linux, macOS, FreeBSD, NetBSD, OpenBSD, Solaris) and uses conditional compilation to select the appropriate bindings for the target platform.

Changes:

  • Removed bindgen from build dependencies and simplified the build script
  • Added pre-generated binding files for all supported platforms
  • Added CI workflow steps to regenerate bindings and verify they remain up-to-date
  • Updated lint attributes to use #[expect] instead of #[allow] where appropriate

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
mtu/Cargo.toml Removed bindgen dependency and updated cargo-machete ignore list
mtu/build.rs Removed bindgen-related code, keeping only platform alias configuration
mtu/src/linux.rs Updated lint attributes and changed to use static binding module path
mtu/src/bsd.rs Updated lint attributes and changed to use static binding module paths per platform
mtu/src/bindings/*.rs Added pre-generated binding files for all supported platforms
mtu/src/bindings/*.h Added header files used as input for binding generation
.github/workflows/check-mtu.yml Added CI jobs to generate bindings and verify they match committed versions
.github/actions/check-vm/action.yml Added bindgen installation and binding generation steps to VM-based tests

@github-actions
Copy link
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to main at f712a7b.

neqo-pr as clientneqo-pr as server
neqo-pr vs. aioquic: A L1 🚀C1
neqo-pr vs. go-x-net: A BP BA
neqo-pr vs. haproxy: ⚠️M A C1 BP BA
neqo-pr vs. kwik: ⚠️C1 BP BA
neqo-pr vs. linuxquic: A L1 🚀C1
neqo-pr vs. lsquic: run cancelled after 20 min
neqo-pr vs. msquic: A L1 C1
neqo-pr vs. mvfst: A L1 C1
neqo-pr vs. neqo: Z
neqo-pr vs. nginx: A ⚠️L1 C1 BP BA
neqo-pr vs. ngtcp2: A ⚠️L1 C1 CM
neqo-pr vs. picoquic: A 🚀L1
neqo-pr vs. quic-go: A 🚀L1
neqo-pr vs. quiche: A 🚀L1 C1 BP BA
neqo-pr vs. quinn: A
neqo-pr vs. s2n-quic: A 🚀BP ⚠️L1 BA CM
neqo-pr vs. tquic: S A 🚀L1 BP BA
neqo-pr vs. xquic: A L1 🚀C1
aioquic vs. neqo-pr: Z 🚀C1 CM
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: Z BP BA CM
lsquic vs. neqo-pr: Z
msquic vs. neqo-pr: Z CM
mvfst vs. neqo-pr: Z A L1 C1 CM
neqo vs. neqo-pr: Z
openssl vs. neqo-pr: LR M A CM
picoquic vs. neqo-pr: Z ⚠️L1
quic-go vs. neqo-pr: 🚀Z BA CM
quiche vs. neqo-pr: Z CM
quinn vs. neqo-pr: Z V2 CM
s2n-quic vs. neqo-pr: ⚠️B CM
tquic vs. neqo-pr: Z CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions
Copy link
Contributor

Benchmark results

No significant performance differences relative to 0392725.

All results
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1504: Change within noise threshold.
       time:   [198.77 ms 199.28 ms 199.89 ms]
       thrpt:  [500.27 MiB/s 501.79 MiB/s 503.10 MiB/s]
change:
       time:   [-1.0332% -0.5630% -0.1117] (p = 0.01 < 0.05)
       thrpt:  [+0.1118% +0.5661% +1.0440]
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1504: No change in performance detected.
       time:   [284.14 ms 286.13 ms 288.15 ms]
       thrpt:  [34.704 Kelem/s 34.949 Kelem/s 35.194 Kelem/s]
change:
       time:   [-0.1582% +0.8310% +1.8096] (p = 0.11 > 0.05)
       thrpt:  [-1.7774% -0.8241% +0.1584]
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1504: No change in performance detected.
       time:   [38.385 ms 38.547 ms 38.740 ms]
       thrpt:  [25.813   B/s 25.942   B/s 26.052   B/s]
change:
       time:   [-0.7211% -0.0900% +0.5955] (p = 0.79 > 0.05)
       thrpt:  [-0.5920% +0.0901% +0.7264]
       No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
5 (5.00%) high mild
4 (4.00%) high severe
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1504: Change within noise threshold.
       time:   [202.81 ms 203.18 ms 203.58 ms]
       thrpt:  [491.21 MiB/s 492.17 MiB/s 493.08 MiB/s]
change:
       time:   [-0.9597% -0.6791% -0.3873] (p = 0.00 < 0.05)
       thrpt:  [+0.3888% +0.6837% +0.9690]
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe
decode 4096 bytes, mask ff: No change in performance detected.
       time:   [5.3191 µs 5.3354 µs 5.3520 µs]
       change: [-0.1551% +0.2777% +0.7155] (p = 0.21 > 0.05)
       No change in performance detected.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
decode 1048576 bytes, mask ff: Change within noise threshold.
       time:   [1.3698 ms 1.3740 ms 1.3783 ms]
       change: [+0.3740% +0.8486% +1.3088] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
decode 4096 bytes, mask 7f: No change in performance detected.
       time:   [7.2239 µs 7.2352 µs 7.2469 µs]
       change: [-0.6918% -0.1366% +0.3334] (p = 0.63 > 0.05)
       No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
3 (3.00%) high mild
2 (2.00%) high severe
decode 1048576 bytes, mask 7f: No change in performance detected.
       time:   [1.8575 ms 1.8616 ms 1.8668 ms]
       change: [-0.1695% +0.1050% +0.4463] (p = 0.51 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
decode 4096 bytes, mask 3f: No change in performance detected.
       time:   [6.9073 µs 6.9202 µs 6.9349 µs]
       change: [-0.1566% +0.4329% +1.5876] (p = 0.37 > 0.05)
       No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
4 (4.00%) high mild
3 (3.00%) high severe
decode 1048576 bytes, mask 3f: No change in performance detected.
       time:   [1.7659 ms 1.7703 ms 1.7762 ms]
       change: [-0.1321% +0.1810% +0.5577] (p = 0.31 > 0.05)
       No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
streams/simulated/1-streams/each-1000-bytes: No change in performance detected.
       time:   [129.68 ms 129.68 ms 129.69 ms]
       thrpt:  [7.5302 KiB/s 7.5305 KiB/s 7.5307 KiB/s]
change:
       time:   [-0.0039% +0.0004% +0.0047] (p = 0.86 > 0.05)
       thrpt:  [-0.0047% -0.0004% +0.0039]
       No change in performance detected.
streams/simulated/1000-streams/each-1-bytes: No change in performance detected.
       time:   [2.5361 s 2.5364 s 2.5366 s]
       thrpt:  [394.22   B/s 394.27   B/s 394.31   B/s]
change:
       time:   [-0.0146% +0.0009% +0.0165] (p = 0.91 > 0.05)
       thrpt:  [-0.0165% -0.0009% +0.0146]
       No change in performance detected.
streams/simulated/1000-streams/each-1000-bytes: No change in performance detected.
       time:   [6.5878 s 6.5985 s 6.6104 s]
       thrpt:  [147.73 KiB/s 148.00 KiB/s 148.24 KiB/s]
change:
       time:   [-0.1783% +0.0423% +0.2497] (p = 0.71 > 0.05)
       thrpt:  [-0.2491% -0.0423% +0.1786]
       No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
9 (9.00%) high severe
streams/walltime/1-streams/each-1000-bytes: No change in performance detected.
       time:   [585.39 µs 587.27 µs 589.45 µs]
       change: [-0.3522% +0.0045% +0.4161] (p = 0.98 > 0.05)
       No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
7 (7.00%) high severe
streams/walltime/1000-streams/each-1-bytes: Change within noise threshold.
       time:   [12.342 ms 12.362 ms 12.383 ms]
       change: [-1.0845% -0.8717% -0.6381] (p = 0.00 < 0.05)
       Change within noise threshold.
streams/walltime/1000-streams/each-1000-bytes: Change within noise threshold.
       time:   [45.039 ms 45.121 ms 45.213 ms]
       change: [-0.9412% -0.7437% -0.5282] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
coalesce_acked_from_zero 1+1 entries: No change in performance detected.
       time:   [92.192 ns 92.878 ns 93.866 ns]
       change: [-0.0900% +0.7396% +1.8121] (p = 0.14 > 0.05)
       No change in performance detected.
Found 16 outliers among 100 measurements (16.00%)
12 (12.00%) high mild
4 (4.00%) high severe
coalesce_acked_from_zero 3+1 entries: No change in performance detected.
       time:   [110.33 ns 110.68 ns 111.05 ns]
       change: [-0.0188% +0.4291% +0.8978] (p = 0.07 > 0.05)
       No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
4 (4.00%) high mild
10 (10.00%) high severe
coalesce_acked_from_zero 10+1 entries: Change within noise threshold.
       time:   [109.88 ns 110.45 ns 111.07 ns]
       change: [+0.0624% +0.5473% +1.0458] (p = 0.03 < 0.05)
       Change within noise threshold.
Found 13 outliers among 100 measurements (13.00%)
3 (3.00%) low mild
10 (10.00%) high severe
coalesce_acked_from_zero 1000+1 entries: Change within noise threshold.
       time:   [94.516 ns 94.741 ns 95.026 ns]
       change: [-1.2191% -0.6831% -0.1136] (p = 0.01 < 0.05)
       Change within noise threshold.
Found 13 outliers among 100 measurements (13.00%)
6 (6.00%) high mild
7 (7.00%) high severe
RxStreamOrderer::inbound_frame(): Change within noise threshold.
       time:   [108.82 ms 108.92 ms 109.02 ms]
       change: [+0.0238% +0.2792% +0.4635] (p = 0.01 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
sent::Packets::take_ranges: No change in performance detected.
       time:   [4.4719 µs 4.5898 µs 4.7172 µs]
       change: [-0.9936% +2.3786% +6.5259] (p = 0.21 > 0.05)
       No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
3 (3.00%) high mild
1 (1.00%) high severe
transfer/simulated/pacing-false/varying-seeds: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/varying-seeds: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-false/same-seed: No change in performance detected.
       time:   [23.941 s 23.941 s 23.941 s]
       thrpt:  [171.09 KiB/s 171.09 KiB/s 171.09 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/simulated/pacing-true/same-seed: No change in performance detected.
       time:   [23.676 s 23.676 s 23.676 s]
       thrpt:  [173.01 KiB/s 173.01 KiB/s 173.01 KiB/s]
change:
       time:   [+0.0000% +0.0000% +0.0000] (p = NaN > 0.05)
       thrpt:  [+0.0000% +0.0000% +0.0000]
       No change in performance detected.
transfer/walltime/pacing-false/varying-seeds: Change within noise threshold.
       time:   [23.179 ms 23.201 ms 23.224 ms]
       change: [+1.1173% +1.2400% +1.3577] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
2 (2.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/varying-seeds: Change within noise threshold.
       time:   [23.592 ms 23.615 ms 23.643 ms]
       change: [+2.2877% +2.4056% +2.5546] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) high mild
2 (2.00%) high severe
transfer/walltime/pacing-false/same-seed: Change within noise threshold.
       time:   [23.277 ms 23.299 ms 23.326 ms]
       change: [+1.5551% +1.6733% +1.8088] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
2 (2.00%) high mild
1 (1.00%) high severe
transfer/walltime/pacing-true/same-seed: Change within noise threshold.
       time:   [23.755 ms 23.789 ms 23.838 ms]
       change: [+2.3750% +2.5512% +2.7552] (p = 0.00 < 0.05)
       Change within noise threshold.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high severe

Download data for profiler.firefox.com or download performance comparison data.

@github-actions
Copy link
Contributor

Client/server transfer results

Performance differences relative to 0392725.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
neqo-neqo-cubic-nopacing 94.7 ± 4.2 86.9 105.4 337.8 ± 7.6 💚 -1.7 -1.8%
neqo-neqo-newreno 96.5 ± 4.1 87.9 105.6 331.6 ± 7.8 💔 1.4 1.4%
neqo-neqo-newreno-nopacing 94.6 ± 4.1 88.5 103.9 338.4 ± 7.8 💚 -2.6 -2.7%
neqo-s2n-cubic 218.0 ± 4.1 212.4 228.2 146.8 ± 7.8 💚 -2.3 -1.0%

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server (params) Mean ± σ Min Max MiB/s ± σ Δ main Δ main
google-google-nopacing 447.4 ± 3.9 441.8 457.8 71.5 ± 8.2
google-neqo-cubic 270.9 ± 4.0 265.3 279.2 118.1 ± 8.0 -1.1 -0.4%
msquic-msquic-nopacing 174.1 ± 59.8 137.3 449.4 183.8 ± 0.5
msquic-neqo-cubic 201.0 ± 53.0 152.2 405.7 159.2 ± 0.6 3.8 1.9%
neqo-google-cubic 744.5 ± 4.8 737.3 766.7 43.0 ± 6.7 -0.4 -0.1%
neqo-msquic-cubic 158.9 ± 4.3 153.6 168.4 201.3 ± 7.4 -0.5 -0.3%
neqo-neqo-cubic 96.9 ± 4.9 86.6 117.1 330.3 ± 6.5 -0.9 -0.9%
neqo-neqo-cubic-nopacing 94.7 ± 4.2 86.9 105.4 337.8 ± 7.6 💚 -1.7 -1.8%
neqo-neqo-newreno 96.5 ± 4.1 87.9 105.6 331.6 ± 7.8 💔 1.4 1.4%
neqo-neqo-newreno-nopacing 94.6 ± 4.1 88.5 103.9 338.4 ± 7.8 💚 -2.6 -2.7%
neqo-quiche-cubic 189.2 ± 3.6 184.1 200.2 169.1 ± 8.9 0.8 0.4%
neqo-s2n-cubic 218.0 ± 4.1 212.4 228.2 146.8 ± 7.8 💚 -2.3 -1.0%
quiche-neqo-cubic 155.9 ± 7.2 145.7 189.4 205.2 ± 4.4 0.2 0.1%
quiche-quiche-nopacing 141.5 ± 3.6 135.9 152.4 226.2 ± 8.9
s2n-neqo-cubic 174.2 ± 5.6 160.9 187.3 183.7 ± 5.7 1.0 0.6%
s2n-s2n-nopacing 251.3 ± 26.9 231.2 350.7 127.3 ± 1.2

Download data for profiler.firefox.com or download performance comparison data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants